package org.wejob.command;

import org.wejob.command.api.TaskDispatcher;
import org.wejob.web.WebClient;

import java.util.Comparator;
import java.util.LinkedList;
import java.util.function.Consumer;
import java.util.stream.Collectors;

public abstract class AbstractTaskDispatcher<T extends WebClient> implements TaskDispatcher<T> {
    private final int cap;
    int handlerNum;
    LinkedList<TaskHandlerImpl> working;
    LinkedList<TaskHandlerImpl> waiting;

    public AbstractTaskDispatcher() {
        this(4);
    }

    public AbstractTaskDispatcher(int cap) {
        this.cap = cap;
    }


    @Override
    public void dispatch(T webClient) {
        if (!this.waiting.isEmpty()) {
            TaskHandlerImpl coder = this.waiting.remove();
            coder.acceptTask(webClient);
            this.working.add(coder);
            coder.notify();
            return;
        }
        if (this.cap > this.handlerNum) {
            TaskHandlerImpl handler = new TaskHandlerImpl(webClient, this, handler());
            this.handlerNum++;
            this.working.add(handler);
            handler.start();
            return;
        }
        this.working.stream().min(Comparator.comparing(TaskHandlerImpl::getTaskNum)).get().acceptTask(webClient);
    }

    synchronized public void removeCoder(TaskHandlerImpl coder) {

    }

    synchronized public void toEmpty(TaskHandlerImpl coder) throws InterruptedException {
        coder.wait();
        this.working = (LinkedList<TaskHandlerImpl>) this.working.stream().filter(c -> c.equals(coder)).collect(Collectors.toList());
        this.waiting.add(coder);
    }

    public abstract Consumer handler();



}
